package com.iflytek.autofly.setting.biz.networking;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.iflytek.autofly.bluetoothservice.util.BluetoothServiceCons;
import com.iflytek.autofly.setting.R;
import com.iflytek.autofly.utils.FlyAssert;
import com.iflytek.autofly.utils.FlyLog;
import com.iflytek.sunflower.FlowerCollector;

import java.util.ArrayList;

/**
 * <b>Description: </b>蓝牙界面可用设备列表的adapter<br/>
 * <b>Change History:</b><br/>
 * <table border="1">
 * <tr>
 * <td><b>user</b></td>
 * <td><b>date</b></td>
 * <td><b>time</b></td>
 * <td><b>reason</b></td>
 * </tr>
 * <tr>
 * <td>JunLuan@iflytek.com</td>
 * <td>2015年5月26日</td>
 * <td>上午10:12:43</td>
 * <td>创建此文件</td>
 * </tr>
 * </table>
 *
 * @author JunLuan@iflytek.com
 */
public class BtDeviceListAdapter extends BaseAdapter {
    private static final String TAG = "BtDeviceListAdapter";
    protected ArrayList<BtDeviceBean> mItems;
    protected ArrayList<BtDeviceBean> mScanedItems;
    protected Activity mActivity;
    private BluetoothSetting mBtManager;
    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            BtDeviceBean bean = (BtDeviceBean) v.getTag();
            if (bean == null) {
                return;
            }
            FlowerCollector.onEvent(mActivity.getApplicationContext(), mActivity.getString(R.string.networking) + "-" + mActivity.getString(R.string.net_bluetooth) + "-" + bean.getAction(), "button_click");
            switch (bean.getState()) {
                case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECT_FAILED:
                case BluetoothServiceCons.ConnectionStatus.CONNECTION_DISCONNECT:
                    FlyAssert.flyAssert(mBtManager != null);
                    FlyAssert.flyAssert(bean != null);
                    mBtManager.connect(bean);
                    break;
                case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECTED:
                    mBtManager.cancelConnect(bean);
                    break;
                case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECTING:
                    mBtManager.cancelConnect(bean);
                    break;
                case BluetoothServiceCons.ConnectionStatus.CONNECTION_UNPAIRED:
                    mBtManager.connect(bean);
                    break;
                default:
                    FlyLog.e(TAG, "unknown status[" + bean.getState() + "]");
            }
        }
    };

    public BtDeviceListAdapter(final Activity activity) {
        super();
        // 初始化
        mActivity = activity;
        mItems = new ArrayList<BtDeviceBean>();
        mScanedItems = new ArrayList<BtDeviceBean>();
    }

    public void setBtMngr(BluetoothSetting btManager) {
        mBtManager = btManager;
    }

    @Override
    public int getCount() {
        return mItems.size() + mScanedItems.size();
    }

    @Override
    public Object getItem(int index) {
        if (index < mItems.size()) {
            return mItems.get(index);
        } else {
            return mScanedItems.get(index - mItems.size());
        }
    }

    @Override
    public long getItemId(int index) {
        return index;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View view;
        if (convertView == null) {
            LayoutInflater lf = LayoutInflater.from(mActivity);
            view = lf.inflate(R.layout.net_bt_device_list_item, null);
        } else {
            view = convertView;
        }

        final BtDeviceBean bean = (BtDeviceBean) getItem(position);
        view.setTag(bean);


        TextView deviceNameTv = (TextView) view.findViewById(R.id.net_bt_device_name_tv);
        TextView deviceStatusTv = (TextView) view.findViewById(R.id.net_bt_device_status_tv);
        Button deviceActionBtn = (Button) view.findViewById(R.id.net_bt_device_action_btn);
        ImageView checkedIv = (ImageView) view.findViewById(R.id.net_bt_item_selected_iv);
        deviceNameTv.setFocusable(false);
        deviceStatusTv.setFocusable(false);
        deviceActionBtn.setFocusable(false);

        deviceNameTv.setVisibility(View.VISIBLE);
        deviceStatusTv.setVisibility(View.VISIBLE);
        deviceActionBtn.setVisibility(View.VISIBLE);
        checkedIv.setVisibility(View.GONE);

        deviceActionBtn.setTextColor(mActivity.getResources().getColor(R.color.net_bt_device_action_btn_fontcolor));

        deviceActionBtn.setTag(bean);
        deviceActionBtn.setOnClickListener(mOnClickListener);
        switch (bean.getState()) {
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_DISCONNECT:
                deviceActionBtn.setEnabled(true);
                deviceActionBtn.setBackgroundResource(R.drawable.net_bt_action_paired);
                break;
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECTED:
                deviceActionBtn.setEnabled(true);
                deviceActionBtn.setTextColor(mActivity.getResources().getColor(R.color.net_bt_device_action_btn_fontcolor_connected));
                deviceActionBtn.setBackgroundResource(R.drawable.net_bt_action_connected);
                break;
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECTING:
                deviceActionBtn.setEnabled(false);
                deviceActionBtn.setBackgroundResource(R.drawable.net_bt_action_connecting);
                break;
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECT_FAILED:
                deviceActionBtn.setEnabled(true);
                deviceActionBtn.setBackgroundResource(R.drawable.net_bt_action_connect_failed);
                break;
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_UNPAIRED:
                deviceActionBtn.setEnabled(true);
                deviceActionBtn.setBackgroundResource(R.drawable.net_bt_action_unpaired);
                break;
            default:
        }

        String name = bean.getName();
        if (name.length() > 20) {
            name = name.substring(0, 17) + "...";
        }
        deviceNameTv.setText(name);
        deviceStatusTv.setText(bean.getStateInString());
        deviceActionBtn.setText(bean.getAction());
        return view;
    }

    public void setItem(BtDeviceBean bean) {
        doSetItem(bean);
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });
    }

    private void doSetItem(BtDeviceBean bean) {
        removeItemWithoutNotify(bean);

        switch (bean.getState()) {
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECTED:
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECTING:
                // 直接移到已保存列表最上端
                mItems.add(0, bean);
                break;
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_UNPAIRED:
                // 添加到扫描列表最后
                mScanedItems.add(bean);
                break;
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_DISCONNECT:
            case BluetoothServiceCons.ConnectionStatus.CONNECTION_CONNECT_FAILED:
                // 添加到已保存列表最后
                mItems.add(bean);
                break;
            default:
                FlyLog.e(TAG, "unknown state " + bean.getState());
        }
    }


    public void setItem(int index, int state, String stateInString, String action) {
        if (index < getCount()) {
            BtDeviceBean bean = (BtDeviceBean) getItem(index);
            removeItemWithoutNotify(index);
            bean.setState(state);
            bean.setStateInString(stateInString);
            bean.setAction(action);
            mItems.add(0, bean);
        }

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });
    }

    private void removeItemWithoutNotify(int index) {
        if (index < mItems.size()) {
            mItems.remove(index);
        } else {
            mScanedItems.remove(index - mItems.size());
        }
    }


    private void removeItemWithoutNotify(BtDeviceBean bean) {
        int i;
        for (i = 0; i < mItems.size(); i++) {
            if (mItems.get(i).getAddr().equals(bean.getAddr())) {
                mItems.remove(i);
                return;
            }
        }
        for (i = 0; i < mScanedItems.size(); i++) {
            if (mScanedItems.get(i).getAddr().equals(bean.getAddr())) {
                mScanedItems.remove(i);
                return;
            }
        }
    }

    public void removeItem(int position) {
        removeItemWithoutNotify(position);
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });
    }

    public void removeItem(BtDeviceBean bean) {
        int index = findIndexInDeviceList(bean);
        if (index < mItems.size()) {
            removeItem(index);
        }
    }

    public void clearList() {
        mItems.clear();
        mScanedItems.clear();
    }

    public void add(BtDeviceBean model) {
        addToList(mItems, model);
    }


    public void addScan(BtDeviceBean model) {
        addToList(mScanedItems, model);
    }

    public void addToList(ArrayList<BtDeviceBean> list, BtDeviceBean model) {
        int index = findIndexInDeviceList(model);
        if (index == getCount()) {
            list.add(model);
        } else {
            BtDeviceBean bean = (BtDeviceBean) getItem(index);
            bean.setName(model.getName());
            // for sky
            // 有时候会先收到connectting的状态改变，然后又收到ondevicefound
            // 直接设置会导致状态紊乱，此处hold一下
            if (model.getState() != BluetoothServiceCons.ConnectionStatus.CONNECTION_UNPAIRED) {
                bean.setState(model.getState());
                bean.setStateInString(model.getStateInString());
                bean.setAction(model.getAction());
            }
        }
    }

    private int findIndexInDeviceList(BtDeviceBean bean) {
        if (bean == null) {
            return getCount();
        }
        int i;
        for (i = 0; i < mItems.size(); i++) {
            if (mItems.get(i).getAddr().equals(bean.getAddr())) {
                return i;
            }
        }
        for (i = 0; i < mScanedItems.size(); i++) {
            if (mScanedItems.get(i).getAddr().equals(bean.getAddr())) {
                return i + mItems.size();
            }
        }
        return getCount();
    }

    public void clearScanedList() {
        mScanedItems.clear();
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });
    }


    public BtDeviceBean getItem(String address) {
        int i = 0;
        for (i = 0; i < mItems.size(); i++) {
            if (mItems.get(i).getAddr().equals(address)) {
                return mItems.get(i);
            }
        }
        for (i = 0; i < mScanedItems.size(); i++) {
            if (mScanedItems.get(i).getAddr().equals(address)) {
                return mScanedItems.get(i);
            }
        }
        return null;
    }
}
